#include "../includes.h"

void InitDiffTable(E1_ *e1);
void PushDiffTable(E1_ *e1,int Data);
float PopDiffTable(E1_ *e1);

void Init_E1()
{
	SYSTEM.E1.raw_digit_all 		= 0;
	SYSTEM.E1.prev_raw_digit_all 	= 0;
	SYSTEM.E1.raw_digit_all_2 		= 0;
	SYSTEM.E1.STATUS 				= E1_STATUS_NONE;
	SYSTEM.E1.LOCKMODE				= E1_UNLOCKED;
	SYSTEM.E1.enable_counter		= 0;
	SYSTEM.E1.disable_counter		= 0;
	SYSTEM.E1.raw_count_all			= 0;
	SYSTEM.E1.raw_count_diff		= 0;
	SYSTEM.E1.skip_counter = 0;
	SYSTEM.E1.IntervalCounter = 0;
	
	SYSTEM.E2.raw_digit_all 		= 0;
	SYSTEM.E2.prev_raw_digit_all 	= 0;
	SYSTEM.E2.raw_digit_all_2 		= 0;
	SYSTEM.E2.STATUS 				= E1_STATUS_NONE;
	SYSTEM.E2.LOCKMODE				= E1_UNLOCKED;
	SYSTEM.E2.enable_counter		= 0;
	SYSTEM.E2.disable_counter		= 0;
	SYSTEM.E2.raw_count_all			= 0;
	SYSTEM.E2.raw_count_diff		= 0;
	SYSTEM.E2.skip_counter = 0;
	SYSTEM.E2.IntervalCounter = 0;
	
	InitDiffTable(&(SYSTEM.E1));
	InitDiffTable(&(SYSTEM.E2));
	
	SYSTEM.E1.invalid_check_counter	= 0;
	SYSTEM.E1.invalid_counter		= 0;
	SYSTEM.E1.invalid_flag			= OFF;
	SYSTEM.E1.IsE1In				= OFF;
	
	SYSTEM.E2.invalid_check_counter	= 0;
	SYSTEM.E2.invalid_counter		= 0;
	SYSTEM.E2.invalid_flag			= OFF;
	SYSTEM.E2.IsE1In				= OFF;

	SYSTEM.E1.moving_average = 0.0;
	SYSTEM.E2.moving_average = 0.0;

	SYSTEM.E1.Accuracy 			= DEFAULT_E1_ACCURACY;
	SYSTEM.E1.Jitter_Boundary 	= DEFAULT_E1_JITTER_BOUNDARY;
	SYSTEM.E2.Accuracy 			= DEFAULT_E1_ACCURACY;
	SYSTEM.E2.Jitter_Boundary 	= DEFAULT_E1_JITTER_BOUNDARY;
}


void e1_task_each(E1_ *e1, int e1_no, char log_in, char log_out)
{
	char IsE1In;	
	float raw_count_all_MovingAvg;
	

	switch( e1_no ){
		case 1:
					Select8KCounter1();
					e1->raw_digit_all = Read8KCounter();
					break;
		case 2:
					Select8KCounter2();
					e1->raw_digit_all = Read8KCounter();
					break;
	}


	//e1->raw_count_all = 10000000 - (e1->raw_digit_all - e1->prev_raw_digit_all);
	//if(e1->raw_count_all > 50000000) {e1->raw_count_all = 100000000 - e1->raw_count_all;}
	
	e1->raw_count_all = 10000000 - (e1->raw_digit_all - e1->prev_raw_digit_all);
	if(e1->raw_count_all > 50000000) {e1->raw_count_all = e1->raw_count_all - 100000000;}	
	
	e1->raw_count_diff = abs((e1->raw_digit_all - e1->raw_digit_all_2))%10000000;

	if(abs(e1->raw_count_all)>5E6){
		e1->IsE1In = NO;
	}
	else{
		e1->IsE1In = YES;
	}	
	
	
	//1
	if(e1->STATUS != E1_STATUS_RUN){
		PushDiffTable(e1,e1->raw_count_all);
	}
	
	else{
		//2
		if(abs(e1->raw_count_all)<e1->Jitter_Boundary){
			PushDiffTable(e1,e1->raw_count_all);
		}
		//3	
		else{
			e1->invalid_counter++;			
		}
	}
	
	e1->invalid_check_counter++;

	if(e1->invalid_check_counter == E1_INVALID_CHECK_PERIOD){
		if(e1->invalid_counter >= E1_INVALID_CHECK_PERIOD/2){
			e1->invalid_flag = ON;
		}
		else{
			e1->invalid_flag = OFF;
		}
		e1->invalid_check_counter = 0;
		e1->invalid_counter = 0;
	}
	
	raw_count_all_MovingAvg = PopDiffTable(e1);	
		
	e1->moving_average = raw_count_all_MovingAvg;

	switch(e1->STATUS){

		case E1_STATUS_NONE:

				//Select1PPS8KHZ();
				e1->STATUS = E1_STATUS_SET;
				e1->enable_counter = 0;
				e1->disable_counter = 0;
				e1->IntervalCounter = 0;
				break;

		case E1_STATUS_SET:

				e1->IntervalCounter++;

				if( e1->IntervalCounter == 1 ){

					ResetClear8KCounter();
				}
				else if( e1->IntervalCounter == 3 ){

					SetClear8KCounter();
				}


				//if((e1->raw_count_all > -6 && e1->raw_count_all < 6) && (raw_digit_all == raw_digit_all_2)){
				//if((e1->raw_count_all >= -E1_RECOGNITION_DIF && e1->raw_count_all <= E1_RECOGNITION_DIF) ){ //&& (e1->raw_count_diff == 0)
				if((raw_count_all_MovingAvg >= -1*(e1->Accuracy) && raw_count_all_MovingAvg <= e1->Accuracy) ){ //&& (e1->raw_count_diff == 0)				
					e1->enable_counter++;
					e1->disable_counter = 0;
				}
				else {
					e1->enable_counter = 0;
					e1->disable_counter++;
				}

				if( e1->enable_counter > E1_RECOGNITION_COUNT ){

					e1->STATUS = E1_STATUS_RUN;
					e1->disable_counter = 0;
					e1->IntervalCounter = 0;

				    if (SYSTEM.IO.CTRL_PORT.MODE == UDEBUG){
						sprintf(MESG,"8K[%d] - in\r\n",e1_no);
						TransmitMessage((BYTE*)MESG,PORT_CONTROL);
					}
					LogIt(LOG_CATA1_NORM, LOG_CATA2_NOTHING, log_in,0);

					//Recovery_Offset = 0;
				}

				if( e1->disable_counter > 5 ){

					e1->STATUS = E1_STATUS_NONE;
					//InitDiffTable(e1);
				}
				break;

		case E1_STATUS_RUN:

				e1->IntervalCounter++;
				
				
				if(! ((raw_count_all_MovingAvg >= -1*(e1->Accuracy) && raw_count_all_MovingAvg <= e1->Accuracy) ) ||
				
					(e1->invalid_flag == ON) || (e1->IsE1In == NO)){
				
					e1->disable_counter++;
				}
				else {
					e1->disable_counter = 0;
				}

				if( e1->disable_counter >= 5 ){

					e1->STATUS = E1_STATUS_NONE;
					
					InitDiffTable(e1);

				    if (SYSTEM.IO.CTRL_PORT.MODE == UDEBUG){
						sprintf(MESG,"8K[%d] - out\r\n",e1_no);
						TransmitMessage((BYTE*)MESG,PORT_CONTROL);
					}

					LogIt(LOG_CATA1_NORM, LOG_CATA2_NOTHING, log_out,0);
				}
				break;

	}

	
    if (SYSTEM.IO.CTRL_PORT.MODE == UDEBUG6){
       	sprintf((char*)MESG,"[%d] ES:%d ro:%d rd1:%d rd2:%d rd:%d ec:%d dc:%d "
       						"ro_ma:%.2f %d "
       						"Iv:%d %d "
       						"In:%d\r\n",
       						e1_no,e1->STATUS,e1->raw_count_all,e1->raw_digit_all,e1->raw_digit_all_2,e1->raw_count_diff,e1->enable_counter,e1->disable_counter,
       						raw_count_all_MovingAvg,e1->diff_table_counter,
       						e1->invalid_flag,e1->invalid_counter,
       						e1->IsE1In);
        TransmitMessage((BYTE*)MESG,DEBUG_PORT);
    }   

	e1->prev_raw_digit_all = e1->raw_digit_all;


}


void e1_task()
{
	e1_task_each(&SYSTEM.E1,1,LOG_E1_In,LOG_E1_Out);
	//e1_task_each(&SYSTEM.E2,2,LOG_E2_In,LOG_E2_Out);
}



void e1_task2_each(E1_ *e1, int e1_no)
{
	switch( e1_no ){
		case 1:
					Select8KCounter1();
					e1->raw_digit_all_2 = Read8KCounter();
					break;
		case 2:
					Select8KCounter2();
					e1->raw_digit_all_2 = Read8KCounter();
					break;
	}

    //e1->raw_digit_all_2 = ReadMainCounterAll();

}

void e1_task2()
{

	e1_task2_each(&SYSTEM.E1,1);
	e1_task2_each(&SYSTEM.E2,2);

}


void InitDiffTable(E1_ *e1)
{
	int i;
	e1->diff_table_counter = 0;
	e1->diff_table_index = 0;
	e1->diff_table_sum = 0;
	
	for(i=0;i<DIFF_TABLE_SIZE;i++){
		e1->diff_table[i] = 0;
	}
}

void PushDiffTable(E1_ *e1,int Data)
{
	if(e1->diff_table_counter<DIFF_TABLE_SIZE){
		e1->diff_table_index = e1->diff_table_counter;
		e1->diff_table[e1->diff_table_index] = Data;
		e1->diff_table_sum += Data;
		e1->diff_table_counter++;
	}
	else{
		e1->diff_table_counter = DIFF_TABLE_SIZE;

		if(e1->diff_table_index >= (DIFF_TABLE_SIZE-1)){
			e1->diff_table_index = 0;
		}
		else{
			e1->diff_table_index++;
		}
		e1->diff_table_sum	= e1->diff_table_sum + Data - e1->diff_table[e1->diff_table_index];
		e1->diff_table[e1->diff_table_index] = Data;
	}
}

float PopDiffTable(E1_ *e1)
{
	float ret_val;

	if(e1->diff_table_counter<DIFF_TABLE_SIZE){
		ret_val = (float)50E6;//0� ƴ�Ⱚ ��
	}
	else{
		ret_val = (float)(e1->diff_table_sum/(float)DIFF_TABLE_SIZE);
	}
	
	return ret_val;
}


